/*
 * IpcRemoto.cpp
 *
 *  Created on: 14/08/2014
 *      Author: migue
 */

#include "IpcRemoto.h"
#include <syslog.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

IpcRemoto::IpcRemoto(int idCliente, int idIpc) :
_cEnvio(RUTA, COLASISTEMA), _cRecibo(RUTA, COLARECIBO_CLI)
{
	_idCliente = idCliente;
	_idIpc = idIpc;

	_version = 0;
}

IpcRemoto::~IpcRemoto() {

}


void IpcRemoto::cerrarConexion() {
	_msj.destinatario = _idCliente;
	_msj.origen = _idCliente;
	_msj.destinatarioFinal = _idBroker;

	_msj.tipo = Tipos::MSJ_NORMAL;
	_msj._ipc.op_ipc = TIPO_FINALIZAR;

	_cEnvio.enviar(&_msj, TAM_MENSAJE);

	usleep(1000);

	waitpid(-1, 0, WNOHANG);
	waitpid(-1, 0, WNOHANG);
}

void IpcRemoto::iniciarConexion() {
	char arg[20];
	int pid;

	sprintf(arg, "%i", _idCliente);

	pid = fork();
	if (pid == 0) {
		execl("./conexBrokerCliente", "conexBrokerCliente", arg, "E", NULL);
		syslog(LOG_ERR, "Error al lanzar proceso de conexion con Broker, idCliente: %i ", _idCliente);
		exit(EXIT_FAILURE);
	}

	pid = fork();
	if (pid == 0) {
		execl("./conexBrokerCliente", "conexBrokerCliente", arg, "R", NULL);
		syslog(LOG_ERR, "Error al lanzar proceso de conexion con Broker, idCliente: %i", _idCliente);
		exit(EXIT_FAILURE);
	}
}


void IpcRemoto::enviarPedido() {
	TipoMensaje tipoEnvioIPC = _msj._ipc.op_ipc;

	_msj.destinatario = _idCliente;
	_msj.origen = _idCliente;

	_msj.destinatarioFinal = -1; // el conexcliente se encarga de colocal el id del Broker conectado

	_msj._ipc.id_ipc = _idIpc;

	_msj.tipo = Tipos::MSJ_IPC;
	_msj._ipc.version = _version;

	_cEnvio.enviar(&_msj, TAM_MENSAJE);


	bool seguirEsperando = false;

	memset(&_recibido, 0, sizeof(_recibido));

	do {
		_cRecibo.recibir(&_recibido,TAM_MENSAJE, _idCliente);

		if (_recibido.tipo != Tipos::MSJ_IPC ||
				_recibido._ipc.op_ipc != tipoEnvioIPC ||
				_recibido._ipc.id_ipc != _idIpc ||
				_recibido._ipc.version != _version)
		{
			seguirEsperando= true;
			// vuelvo a poner el mensaje en la cola
			_cRecibo.enviar(&_recibido, TAM_MENSAJE);
			memset(&_recibido, 0, sizeof(_recibido));
			usleep(100);
		}
		else {
			seguirEsperando = false;
		}

	} while (seguirEsperando);

	_version++;

	memcpy(&_msj,&_recibido, sizeof(_msj));
}


